<?php
class UHU_microformats_hCalendar_Parser extends UHU_microformats_hCalendar
{
	const xpath_vevent             = './/*[contains(@class,"vevent")]';
	const xpath_vevent_summary     = './/*[contains(@class,"summary")]';
	const xpath_vevent_description = './/*[contains(@class,"description")]';
	const xpath_vevent_dtstart     = './/*[contains(@class,"dtstart")]';
	const xpath_vevent_dtend       = './/*[contains(@class,"dtend")]';
	const xpath_vevent_location    = './/*[contains(@class,"location")]';
	const xpath_url                = './/*[contains(@class,"url")]';
	const xpath_a                  = './/a';
	const xpath_vevent_organizer   = './/*[contains(@class,"organizer")]';
	protected $document;
	protected $DOMDocument;
	public function __construct($url,$event_class,$hCard_class,$callback=null)
	{
		if(($ch = curl_init($url)) === false)
		{
			throw new RuntimeException('Could not initialise cURL.');
		}
		curl_setopt($ch,CURLOPT_HEADER,false);
		curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
		if(($this->document = curl_exec($ch)) === false)
		{
			throw new RuntimeException('Execution of cURL failed.');
		}
		curl_close($ch);;
		if(isset($callback) === true)
		{
			$this->document = call_user_func_array($callback,array($this->document));
		}
		try
		{
			$this->DOMDocument = new DOMDocument;
			$this->DOMDocument->strictErrorChecking = false;
			if(($this->DOMDocument instanceof DOMDocument) === false)
			{
				throw new Exception;
			}
		}
		catch(Exception $e)
		{
			throw new RuntimeException('Could not create instance of DOMDocument.');
		}
		try
		{
			if($this->DOMDocument->loadHTML($this->document) === false)
			{
				throw new Exception;
			}
		}
		catch(\ErrorException $e)
		{
			if(preg_match('/^DOMDocument::loadHTML\(\): ID (.+) already defined in Entity/',$e->getMessage(),$matches) === 1)
			{
				throw new RuntimeException('Could not load HTML: Duplicate HTML id attributes found (' . $matches[1] . ').');
			}
			else
			{
				throw new RuntimeException('Could not load HTML into DOMDocument instance.');
			}
		}
		catch(\Exception $e)
		{
			throw new RuntimeException('Could not load HTML into DOMDocument instance.');
		}
		$this->_parse_vevents($this->DOMDocument,$event_class,$hCard_class);
	}
	protected function _parse_vevents(DOMDocument $DOMDocument,$event_class,$hCard_class)
	{
		$possible = self::xpath($DOMDocument,self::xpath_vevent);
		if($possible->length === 0)
		{
			return false;
		}
		for($x=0;$x<$possible->length;++$x)
		{
			try
			{
				$summary     = $this->_summary($DOMDocument,$possible->item($x));
				$dtstart     = $this->_dtstart($DOMDocument,$possible->item($x));
				$description = $this->_description($DOMDocument,$possible->item($x));
				$dtend       = $this->_dtend($DOMDocument,$possible->item($x));
				$location    = $this->_location($DOMDocument,$possible->item($x),$hCard_class);
	#			$organizer   = $this->organizer($DOMDocument,$possible->item($x));
			}
			catch(RuntimeException $e)
			{
				continue;
			}
			$this[] = new $event_class($summary,$dtstart,$dtend,$description,$location);#,$organizer);
		}
		if($this->count() === 0)
		{
			return false;
		}
		else
		{
			return $this;
		}
	}
	protected static function xpath(DOMDocument $DOMDocument,$query,DOMNode $node=null)
	{
		try
		{
			$xpath = new DOMXPath($DOMDocument);
			if(($xpath instanceof DOMXPath) === false)
			{
				throw new Exception;
			}
		}
		catch(Exception $e)
		{
			throw new RuntimeException('Could not create instance of DOMXPath.');
		}
		try
		{
			$result = isset($node) ? $xpath->query($query,$node) : $xpath->query($query);
			if(($result instanceof DOMNodeList) === false)
			{
				throw new Exception;
			}
		}
		catch(\Exception $e)
		{
			throw new RuntimeException('Could not execute XPath query.');
		}
		return $result;
	}
	protected function _summary(DOMDocument $DOMDocument,DOMNode $node=null)
	{
		$summary = self::xpath($DOMDocument,self::xpath_vevent_summary,$node);
		if($summary->length === 0)
		{
			throw new RuntimeException('No summary found.');
		}
		else
		{
			return $summary->item(0)->textContent;
		}
	}
	protected function _description(DOMDocument $DOMDocument,DOMNode $node=null)
	{
		$description = self::xpath($DOMDocument,self::xpath_vevent_description,$node);
		return ($description->length > 0) ? str_replace("\n",'\n',trim($description->item(0)->textContent)) : null;
	}
	protected function _dtstart(DOMDocument $DOMDocument,DOMNode $node=null)
	{
		$dtstart = self::xpath($DOMDocument,self::xpath_vevent_dtstart,$node);
		if($dtstart->length === 0)
		{
			throw new RuntimeException('No DTSTART found.');
		}
		else
		{
			if($dtstart->item(0)->hasAttributes() === false || $dtstart->item(0)->attributes->getNamedItem('title') === null)
			{
				$foo = $dtstart->item(0)->textContent;
			}
			else
			{
				$foo = $dtstart->item(0)->attributes->getNamedItem('title')->textContent;
			}
			$dtstart = new UHU_moment(gmdate('Ymd\THis',strtotime($foo)));
		}
		return $dtstart;
	}
	protected function _dtend(DOMDocument $DOMDocument,DOMNode $node=null)
	{
		$dtend = self::xpath($DOMDocument,self::xpath_vevent_dtend,$node);
		if($dtend->length === 0)
		{
			$dtend = null;
		}
		else
		{
			if($dtend->item(0)->hasAttributes() === false || $dtend->item(0)->attributes->getNamedItem('title') === null)
			{
				$foo = $dtend->item(0)->textContent;
			}
			else
			{
				$foo = $dtend->item(0)->attributes->getNamedItem('title')->textContent;
			}
			$dtend = new UHU_moment(gmdate('Ymd\THis',strtotime($foo)));
		}
		return $dtend;
	}
	protected function _location(DOMDocument $DOMDocument,DOMNode $node=null,$hCard_class)
	{
		$location = self::xpath($DOMDocument,self::xpath_vevent_location,$node);
		if($location->length === 0)
		{
			$location = null;
		}
		else
		{
			$url  = self::xpath($DOMDocument,self::xpath_url,$location->item(0));
			$_url = self::xpath($DOMDocument,self::xpath_a,$location->item(0));
			if($url->length === 1 && $url->item(0)->hasAttributes() && $url->item(0)->attributes->getNamedItem('href') !== null)
			{
				$location = new $hCard_class($location->item(0)->textContent,$url->item(0)->attributes->getNamedItem('href')->textContent);
			}
			else if($_url->length === 1 && $_url->item(0)->hasAttributes() && $_url->item(0)->attributes->getNamedItem('href') !== null)
			{
				$location = new $hCard_class($location->item(0)->textContent,$_url->item(0)->attributes->getNamedItem('href')->textContent);
			}
			else
			{
				$location = new $hCard_class($location->item(0)->textContent);
			}
		}
		return $location;
	}
/*	protected function _organizer(DOMDocument $DOMDocument,DOMNode $node=null)
	{
		$organizer = self::xpath($DOMDocument,self::xpath_vevent_organizer,$node);
		if($organizer->length === 0)
		{
			$organizer = null;
		}
		else
		{
			$url = self::xpath($DOMDocument,self::xpath_url,$organizer->item(0));
			if($url->length === 0)
			{
				$organizer = new uhu_hCard($organizer->item(0)->textContent);
			}
		}
		return $organizer;
	}*/
}
?>